CloudTrail을 이용해 특정 이벤트 조사하기
안녕하세요! 클래스메소드의 임홍기입니다.
가끔 액세스키를 포함한 코드 배포나 조작 실수 등의 이유로 액세스키가 유출되거나 인해 의도하지 않은 리소스 조작이 일어나곤 하는데요.
오늘은 CloudTrail을 이용해서 특정 액세스키로 만들어진 리소스를 조사해보도록 하겠습니다.
CloudTrail이란?
AWS CloudTrail은 계정의 거버넌스, 규정 준수, 운영 및 위험 감사를 활성화하도록 도와주는 서비스입니다. 사용자, 역할 또는 AWS 서비스가 수행하는 작업은 CloudTrail에 이벤트로 기록됩니다. 이벤트에는 AWS Management 콘솔, AWS Command Line Interface 및 AWS SDK, API에서 수행되는 작업이 포함됩니다.
AWS의 모든 서비스는 API를 통해 이용됩니다. 따라서 이용한 AWS 서비스를 CloudTrail을 이용하여 조사할 수 있으며, 비정상적인 활동을 식별하고 이에 대응할 수 있습니다.
간단하게 말하자면 "누가", "언제", "무엇을" 했는지 알 수 있습니다. 따라서 보안정책에 반한 작업이나 액세스키 유출로 인한 과도한 리소스 생성 등을 조사하고 알릴 수 있습니다.
매니지먼트 콘솔을 이용하여 조사하기
먼저 매니지먼트 콘솔을 이용하면 가장 간단하게 발생한 이벤트에 대해서 조사할 수 있습니다.
CloudTrail의 Event history 탭에서 조사하고픈 시간대와
속성을 선택하는 것으로 이벤트를 필터하여 조사할 수 있습니다.
인스턴스를 하나 만들고 난 뒤 EventName이 RunInstances인 기록을 예를 들어서 조회해 보겠습니다.
세부 정보로는 인스턴스가 생성된 시간과, 만든 IAM 유저명 등이 나오게 되며, 언제 어떤 액세스키로 어느 리전에서 만들어졌는지도 확인할 수 있습니다.
참조된 리소스로는 해당 이벤트에 관련된 리소스들이 나오게 됩니다.
이번에는 EC2 인스턴스를 만들었기 때문에 어떤 VPC에서 어떤 KeyPair를 이용하여 만들었는지 등을 알 수 있습니다.
이벤트 레코드는 이벤트 페이로드라고도 하며 이벤트의 전체 JSON 텍스트입니다.
이 레코드에는 요청된 작업을 결정하는데 사용된 모든 정보가 기록되어 있습니다.
CLI를 이용하여 조사하기
CLI 환경에서 CloudTrail을 이용하기 위해서는 lookup-events 명령어를 사용해야 합니다.
가장 간단하게 최근 이벤트 10개를 조사하기 위한 명령어는 아래와 같습니다.
(결과값의 개수를 정해주지 않으면, 최근 90일간의 이벤트가 모두 출력되므로 오랜 시간이 소요되니 주의해주세요!)
$ aws cloudtrail lookup-events --max-results 10
좀 더 검색해야 할 범위를 좁히기 위해서는 이벤트에 따라 매니지먼트 콘솔에서 설정한 것과 같이 다양한 필터값을 넣어주어야 합니다.
[--lookup-attributes <value>] [--start-time <value>] [--end-time <value>] [--event-category <value>] [--cli-input-json | --cli-input-yaml] [--starting-token <value>] [--page-size <value>] [--max-items <value>] [--generate-cli-skeleton <value>] [--cli-auto-prompt <value>]
사용할 수 있는 필터 값은 위와 같으며 value에 들어갈 수 있는 값들도 다양합니다.
예를 들어 --lookup-attributes 속성에 들어갈 수 있는 값은 아래와 같습니다.
[ { "AttributeKey": "EventId"|"EventName"|"ReadOnly"|"Username"|"ResourceType"|"ResourceName"|"EventSource"|"AccessKeyId", "AttributeValue": "string" } ... ]
또한 jq명령어를 이용해 출력된 JSON 결과값을 일관적으로 표현하거나 추가로 필터를 할 수 있습니다.
예제
CLI로 특정 이벤트를 호출하는 방법에 대해 예제를 통해 알아보겠습니다.
다음 예제는 버지니아 리전에서 9월6일 9시부터 9월7일 22시50분까지 발생한 이벤트 중 액세스키 ABCDEFGHIJK가 사용된 이벤트만을 호출하는 명령어입니다.
aws cloudtrail lookup-events \ --region us-east-1 \ --start-time "09-06-2020, 09:00 AM" \ --end-time "09-07-2020, 10:50 PM" \ --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=ABCDEFGHIJK
결과값으론 아래와 같이 출력됩니다.
{ "EventId": "27a1bf0b-de54-4153-b37c-000000000", "Username": "testuser", "EventTime": 1599485838.0, "CloudTrailEvent": "{\"eventVersion\":\"1.05\",\"userIdentity\":{\"type\":\"IAMUser\",\"principalId\":\"...중략}", "AccessKeyId": "ABCDEFGHIJK", "EventName": "TerminateInstances", "ReadOnly": "false", "EventSource": "ec2.amazonaws.com", "Resources": [ { "ResourceType": "AWS::EC2::Instance", "ResourceName": "i-000000000000000" }
필요한 대부분의 정보는 CloudTrailEvent에서 확인할 수 있음으로, 다른 불필요한 정보를 필터하면 더욱 알아보기 쉽게 출력할 수 있습니다.
다음 예제는 '서울 리전'에서 '10월1일 오전 9시부터 10월2일 오후 10시50분까지' 특정 '액세스키'로 'EC2 서비스'에서 발생한 이벤트 중 'Describe 이벤트를 제외한' 모든 이벤트를 조사하는 명령어입니다.
출력 결과값으론 이벤트 발생시간과, 이벤트 명, 이벤트가 발생한 서비스, 리전, 인스턴스가 만들어졌다면 인스턴스의 타입이 나오게 설정하였습니다.
aws cloudtrail lookup-events \ --region ap-northeast-2 \ --start-time "10-01-2020, 09:00 AM" \ --end-time "10-02-2020, 10:50 PM" \ --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=ABCDEFGHIJK\ | jq -r '.Events[].CloudTrailEvent' \ | jq '{eventTime, eventName, eventSource, awsRegion, "instanceType": .responseElements.instancesSet.items[0].instanceType} | select(.eventName | startswith("Describe") | not) | select(.eventSource == "ec2.amazonaws.com")'
결과값으론 아래와 같이 출력됩니다.
{ "eventTime": "2020-10-01T13:35:58Z", "eventName": "RunInstances", "eventSource": "ec2.amazonaws.com", "awsRegion": "ap-northeast-2", "instanceType": "t2.micro" }
이상으로 CloudTrail서비스를 이용하여 이벤트를 조사하는 방법에 대해 알아보았습니다.
사용한 명령어 및 jq메뉴얼 등은 아래에 기재해놓았으니 참고해주세요!